#include <gtest/gtest.h>
#include "../mqserver/mq_host.hpp"

using empty_map=std::unordered_map<std::string,std::string>;

class HostTest : public testing::Test
{
    public:
        void SetUp() override
        {
            _host=std::make_shared<castlemq::VirtualHost>("host1","./data/host1/message","./data/host1/host1.db");
            _host->declareExchange("exchange1",castlemq::ExchangeType::DIRECT,true,false,empty_map());
            _host->declareExchange("exchange2",castlemq::ExchangeType::DIRECT,true,false,empty_map());
            _host->declareExchange("exchange3",castlemq::ExchangeType::DIRECT,true,false,empty_map());
            
            _host->declareQueue("queue1",true,false,false,empty_map());
            _host->declareQueue("queue2",true,false,false,empty_map());
            _host->declareQueue("queue3",true,false,false,empty_map());

            _host->bind("exchange1","queue1","news.music.#");
            _host->bind("exchange1","queue2","news.music.#");
            _host->bind("exchange1","queue3","news.music.#");

            _host->bind("exchange2","queue1","news.music.#");
            _host->bind("exchange2","queue2","news.music.#");
            _host->bind("exchange2","queue3","news.music.#");

            _host->bind("exchange3","queue1","news.music.#");
            _host->bind("exchange3","queue2","news.music.#");
            _host->bind("exchange3","queue3","news.music.#");

            _host->basicPublish("queue1",nullptr,"hello world-1!");
            _host->basicPublish("queue1",nullptr,"hello world-2!");
            _host->basicPublish("queue1",nullptr,"hello world-3!");

            _host->basicPublish("queue2",nullptr,"hello world-1!");
            _host->basicPublish("queue2",nullptr,"hello world-2!");
            _host->basicPublish("queue2",nullptr,"hello world-3!");

            _host->basicPublish("queue3",nullptr,"hello world-1!");
            _host->basicPublish("queue3",nullptr,"hello world-2!");
            _host->basicPublish("queue3",nullptr,"hello world-3!");

        }

        void TearDown() override
        {
            _host->clear();
        }
    public:
    castlemq::VirtualHost::ptr _host;
};


TEST_F(HostTest,init_test)
{
    ASSERT_EQ(_host->existsExchange("exchange1"),true);
    ASSERT_EQ(_host->existsExchange("exchange2"),true);
    ASSERT_EQ(_host->existsExchange("exchange3"),true);

    ASSERT_EQ(_host->existsQueue("queue1"),true);
    ASSERT_EQ(_host->existsQueue("queue2"),true);
    ASSERT_EQ(_host->existsQueue("queue3"),true);

    ASSERT_EQ(_host->existsBinding("exchange1","queue1"),true);
    ASSERT_EQ(_host->existsBinding("exchange1","queue2"),true);
    ASSERT_EQ(_host->existsBinding("exchange1","queue3"),true);

    ASSERT_EQ(_host->existsBinding("exchange2","queue1"),true);
    ASSERT_EQ(_host->existsBinding("exchange2","queue2"),true);
    ASSERT_EQ(_host->existsBinding("exchange2","queue3"),true);

    ASSERT_EQ(_host->existsBinding("exchange3","queue1"),true);
    ASSERT_EQ(_host->existsBinding("exchange3","queue2"),true);
    ASSERT_EQ(_host->existsBinding("exchange3","queue3"),true);

    castlemq::MessagePtr msg1= _host->basicConsume("queue1");
    ASSERT_EQ(msg1->payload().body(),std::string("hello world-1!"));
    castlemq::MessagePtr msg2= _host->basicConsume("queue1");
    ASSERT_EQ(msg2->payload().body(),std::string("hello world-2!"));
    castlemq::MessagePtr msg3= _host->basicConsume("queue1");
    ASSERT_EQ(msg3->payload().body(),std::string("hello world-3!"));
    castlemq::MessagePtr msg4= _host->basicConsume("queue1");
    ASSERT_EQ(msg4.get(),nullptr);
}

TEST_F(HostTest,removeExchange_test)
{
    _host->deleteExchange("exchange1");
    ASSERT_EQ(_host->existsBinding("exchange1","queue1"),false);
    ASSERT_EQ(_host->existsBinding("exchange1","queue2"),false);
    ASSERT_EQ(_host->existsBinding("exchange1","queue3"),false);
}

TEST_F(HostTest,removeQueue_test)
{
    _host->deleteQueue("queue1");
    ASSERT_EQ(_host->existsBinding("exchange1","queue1"),false);
    ASSERT_EQ(_host->existsBinding("exchange2","queue1"),false);
    ASSERT_EQ(_host->existsBinding("exchange3","queue1"),false);

    castlemq::MessagePtr msg1= _host->basicConsume("queue1");
    ASSERT_EQ(msg1.get(),nullptr);
}

int main(int argc,char* argv[])
{
    testing::InitGoogleTest(&argc,argv);
    RUN_ALL_TESTS();
    return 0;
}